#
# MainWindow.py
# (c) 2008 Will Baker.
#

import re

from PyQt4.QtCore import Qt, QObject, SIGNAL, QTimer, QSettings, QVariant, QPoint, QSize
from PyQt4.QtGui import QMainWindow, QWidget, QSplitter, QHBoxLayout, QStatusBar

from model import Comic, ComicLoader, Library, Bookmark

from ComicBrowser import ComicBrowser
from SearchView import SearchView
from ComicViewer import ComicViewer
from SetupDialog import SetupDialog

import version

class MainWindow(QMainWindow):
    """
    The MainWindow of the application.
    """
    def __init__( self, parent=None ):
        QMainWindow.__init__( self, parent )
        self.library = None
        self.recent_pages = []
        
        # Create widgets
        central_widget = QSplitter( self )
        central_widget.setOrientation( Qt.Vertical )
        
        self.comic_browser = ComicBrowser()
        search_view = SearchView()
        central_widget.addWidget( search_view )
        central_widget.addWidget( self.comic_browser )
        
        # Set up widget layout
        self.setCentralWidget( central_widget )
        
        # Set up connections
        QObject.connect( search_view,        SIGNAL("search_submitted"), self.on_search )
        QObject.connect( search_view,        SIGNAL("previous_page"),    self.comic_browser.on_previous_page )
        QObject.connect( search_view,        SIGNAL("next_page"),        self.comic_browser.on_next_page )
        QObject.connect( self.comic_browser, SIGNAL("item_entered"),     self.on_item_entered )
        QObject.connect( self.comic_browser, SIGNAL("item_selected"),    self.on_item_selected )
        
        self.resize( 640, 480 )
        self.setWindowTitle( version.Title + " | " + version.Number )
        
        self.load_configuration_settings()
        self.load_session_settings()
        
        self.on_search( "/recent" )
        
    def show_comic( self, comic, page=0 ):
        """
        Open a new ComicViewer with the given Comic.
        """
        c = ComicViewer( comic, self, Qt.Window )
        QObject.connect( c, SIGNAL("previous_item"), self.on_previous_item )
        QObject.connect( c, SIGNAL("next_item"),     self.on_next_item )
        QObject.connect( c, SIGNAL("comic_closed"),  self.on_comic_closed )
        c.setFocus()
        c.set_page( page )
        c.show()
        
    def add_recent_page( self, comic, page ):
        """
        Add a page to the list of recently viewed pages.
        """
        if len(self.recent_pages) >= 32:
            self.recent_pages.pop( 0 )
            
        for b in self.recent_pages:
            if b.comic == comic:
                b.page = page
                self.recent_pages.remove( b )
                
        for b in range(0, len(self.recent_pages)):
            self.recent_pages[b].comic.tags['/recent'].order = len(self.recent_pages)+1-b
                
        self.recent_pages.append( Bookmark(comic, page) )
        self.library.apply_tag( "/recent", comic, 0 )
        
    def on_comic_closed( self, comic, page ):
        """
        Add a recently closed comic to the list of recent pages.
        """
        self.add_recent_page( comic, page )

    def on_search( self, search_string ):
        """
        A search has been submitted.
        """
        results = self.library.find_comics( search_string )        
        self.comic_browser.set_results( results )
        
    def on_item_entered( self, item ):
        """
        The user has move the mouse over an item in the ComicBrowser.
        """
        pass
        
    def on_item_selected( self, item ):
        """
        The user has selected an item in the ComicBrowser.
        """
        # Attempt to find the comic in the recently read list
        page = 0
        for b in self.recent_pages:
            if b.comic == item.comic:
                page = b.page
        self.show_comic( item.comic, page )
        
    def on_previous_item( self, viewer ):
        """
        Find the item preceding the viewer's current item in the result set.
        """
        item = self.library.find_adjacent_comic( viewer.comic, -1 )
        if item:
            viewer.set_comic( item )
        
    def on_next_item( self, viewer ):
        """
        Find the item succeeding the viewer's current item in the result set.
        """
        item = self.library.find_adjacent_comic( viewer.comic, 1 )
        if item:
            viewer.set_comic( item )
        
    def load_session_settings( self ):
        """
        Load session specific settings.
        """
        settings = QSettings( QSettings.IniFormat, QSettings.UserScope, "OpenTome", "session" )
        
        settings.beginGroup( "MainWindow" )
        pos   = settings.value( "pos", QVariant(QPoint(0, 0)) ).toPoint()
        size  = settings.value( "size", QVariant(QSize(640, 480)) ).toSize()
        settings.endGroup()
        pages = settings.value( "recent_pages" ).toStringList()
        
        self.resize( size )
        self.move( pos )
        for p in pages:
            s = str(p).split('$')
            path = s[0]
            page = int(s[1])
            comic = self.library.find_comic_by_path( path )
            if comic:
                self.add_recent_page( comic, page )
        
    def save_session_settings( self ):
        """
        Load session specific settings.
        """
        settings = QSettings( QSettings.IniFormat, QSettings.UserScope, "OpenTome", "session" )
        
        settings.beginGroup( "MainWindow" )
        settings.setValue( "pos", QVariant(self.pos()) )
        settings.setValue( "size", QVariant(self.size()) )
        settings.endGroup()
        
        pages = []
        for p in self.recent_pages:
            pages.append( p.comic.path + "$" + str(p.page) )
        settings.setValue( "recent_pages", QVariant(pages) )
        
    def load_configuration_settings( self ):
        """
        Load configuration settings from disk. This is necessary to find the plugins directory
        and the library directory.
        """
        settings = QSettings( QSettings.IniFormat, QSettings.UserScope, "OpenTome", "configuration" )
        
        settings.beginGroup( "library" )
        library_path = str(settings.value( "library_path", QVariant("") ).toString())
        plugins_path = str(settings.value( "plugins_path", QVariant("") ).toString())        
        settings.endGroup()
        
        if library_path == "" or plugins_path == "":
            setup_dialog = SetupDialog( library_path, plugins_path, self )
            setup_dialog.exec_()
            
            library_path = setup_dialog.library_path
            plugins_path = setup_dialog.plugins_path

            self.save_configuration_settings( library_path, plugins_path )

        # Load plugins
        ComicLoader.load_plugins( plugins_path, version.Platform )

        # Load library
        self.library = Library( library_path )

    def save_configuration_settings( self, library_path, plugins_path ):
        """
        Save the configuration settings.
        """
        settings = QSettings( QSettings.IniFormat, QSettings.UserScope, "OpenTome", "configuration" )
        
        settings.beginGroup( "library" )
        settings.setValue( "library_path", QVariant(library_path) )
        settings.setValue( "plugins_path", QVariant(plugins_path) )
        settings.endGroup()
        
        settings.beginGroup( "view" )
        settings.endGroup()
        
    def closeEvent( self, e ):
        self.comic_browser.clear()
        self.save_session_settings()
         
